package com.zfy.tingshu.album.service.impl;

import com.alibaba.fastjson.JSONObject;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.zfy.tingshu.album.mapper.AlbumAttributeValueMapper;
import com.zfy.tingshu.album.mapper.AlbumInfoMapper;
import com.zfy.tingshu.album.mapper.AlbumStatMapper;
import com.zfy.tingshu.album.service.AlbumAttributeValueService;
import com.zfy.tingshu.album.service.AlbumInfoService;
import com.zfy.tingshu.common.cache.TsCache;
import com.zfy.tingshu.common.config.redisson.RedissonConfig;
import com.zfy.tingshu.common.constant.RedisConstant;
import com.zfy.tingshu.common.constant.SystemConstant;
import com.zfy.tingshu.common.rabbit.constant.MqConst;
import com.zfy.tingshu.common.rabbit.service.RabbitService;
import com.zfy.tingshu.common.util.AuthContextHolder;
import com.zfy.tingshu.model.album.AlbumAttributeValue;
import com.zfy.tingshu.model.album.AlbumInfo;
import com.zfy.tingshu.model.album.AlbumStat;
import com.zfy.tingshu.search.client.SearchFeignClient;
import com.zfy.tingshu.search.client.impl.SearchDegradeFeignClient;
import com.zfy.tingshu.vo.album.AlbumAttributeValueVo;
import com.zfy.tingshu.vo.album.AlbumInfoVo;
import com.zfy.tingshu.vo.album.AlbumListVo;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.zfy.tingshu.vo.album.AlbumStatVo;
import lombok.extern.slf4j.Slf4j;
import org.redisson.api.RBloomFilter;
import org.redisson.api.RLock;
import org.redisson.api.RedissonClient;
import org.springframework.amqp.rabbit.core.RabbitTemplate;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Qualifier;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.stereotype.Service;

import javax.annotation.Nullable;
import java.util.ArrayList;
import java.util.List;
import java.util.Random;
import java.util.stream.Collectors;

@Slf4j
@Service
@SuppressWarnings({"all"})
public class AlbumInfoServiceImpl extends ServiceImpl<AlbumInfoMapper, AlbumInfo> implements AlbumInfoService {

	@Autowired
	private AlbumInfoMapper albumInfoMapper;
	@Autowired
	private AlbumAttributeValueMapper albumAttributeValueMapper;
	@Autowired
	private AlbumStatMapper albumStatMapper;
	@Autowired
	AlbumAttributeValueService albumAttributeValueService;

    @Qualifier("com.zfy.tingshu.search.client.SearchFeignClient")
    @Autowired
	SearchFeignClient searchFeignClient;
    @Autowired
    private RabbitService rabbitService;

	@Autowired
	private RedisTemplate redisTemplate;

	@Autowired
	private RedissonClient redissonClient;


	@Override
	public void saveAlbumInfo(AlbumInfoVo albumInfoVo) {
		//从本地线程池中获取用户id
		Long userId = null==AuthContextHolder.getUserId()?1:AuthContextHolder.getUserId();

		AlbumInfo albumInfo = new AlbumInfo();
		BeanUtils.copyProperties(albumInfoVo,albumInfo);
		albumInfo.setUserId(userId);
		//设置试听集数
		if (!SystemConstant.ALBUM_PAY_TYPE_FREE.equals(albumInfo.getPayType())){
			//付费，集数设置
			albumInfo.setTracksForFree(5);
		}
		//设置审核状态，发送一个消息；给管理平台，站内信（提示信息）审核通过：监听消息，完成审核状态赋值
		albumInfo.setStatus(SystemConstant.ALBUM_STATUS_PASS);
		albumInfoMapper.insert(albumInfo);
		List<AlbumAttributeValueVo> albumAttributeValueVoList =
				albumInfoVo.getAlbumAttributeValueVoList();
		ArrayList<AlbumAttributeValue> albumAttributeValues = new ArrayList<>();
		albumAttributeValueVoList.forEach(albumAttributeValueVo -> {
			AlbumAttributeValue albumAttributeValue = new AlbumAttributeValue();
			albumAttributeValue.setAlbumId(albumInfo.getId());
			albumAttributeValue.setAttributeId(albumAttributeValueVo.getAttributeId());
			albumAttributeValue.setValueId(albumAttributeValueVo.getValueId());
			albumAttributeValues.add(albumAttributeValue);

//			albumAttributeValueMapper.insert(albumAttributeValue);
		});
		albumAttributeValueService.saveBatch(albumAttributeValues);

		saveAlbumStat(albumInfo.getId(),SystemConstant.ALBUM_STAT_PLAY);
		saveAlbumStat(albumInfo.getId(),SystemConstant.ALBUM_STAT_SUBSCRIBE);
		saveAlbumStat(albumInfo.getId(),SystemConstant.ALBUM_STAT_BROWSE);
		saveAlbumStat(albumInfo.getId(),SystemConstant.ALBUM_STAT_COMMENT);

		//判断IsOpen状态,0 不公开，1 公开
		if ("1".equals(albumInfoVo.getIsOpen())) {
			//根据albumId上架商品
//			searchFeignClient.upperAlbum(albumInfo.getId());
			rabbitService.sendMessage(MqConst.EXCHANGE_ALBUM,MqConst.ROUTING_ALBUM_UPPER,albumInfo.getId());
			//将专辑Id添加到布隆过滤器
			RBloomFilter<Object> bloomFilter = redissonClient.getBloomFilter(RedisConstant.ALBUM_BLOOM_FILTER);
			bloomFilter.add(albumInfo.getId());
		}

	}

	private void saveAlbumStat(Long id, String albumStatPlay) {
		//创建对象
		AlbumStat albumStat = new AlbumStat();
		albumStat.setAlbumId(id);
		albumStat.setStatType(albumStatPlay);
		albumStat.setStatNum(new Random().nextInt(100000));

		albumStatMapper.insert(albumStat);
	}

	@Override
	public void findUserAlbumPage(IPage<AlbumListVo> page) {
		Long userId = null==AuthContextHolder.getUserId()?1:AuthContextHolder.getUserId();
		albumInfoMapper.findUserAlbumPage(page,userId);
	}

	@Override
	@TsCache(keyPrefix = "album:",keySuffix = ":info")
	public AlbumInfo getAlbumInfo(Long albumId) {
		return getAlbumInfoDB(albumId);

//		//定义String 数据类型
//		String dataKey= RedisConstant.ALBUM_INFO_PREFIX+albumId;
//		//根据缓存的key获取数据
//		AlbumInfo albumInfo = (AlbumInfo) this.redisTemplate.opsForValue().get(dataKey);
//		//判断缓存中是否存在数据；
//		if (null==albumInfo){
//			//不存在；查询数据库；
//			//加锁
//			String lockKey = RedisConstant.ALBUM_LOCK_SUFFIX+albumId;
//			RLock lock=redissonClient.getLock(lockKey);
//			lock.lock();
//			try {
//				//业务逻辑
//				albumInfo = getAlbumInfoDB(albumId);
//			}catch(Exception e){
//				//异常信息
//			}finally {
//				//解锁
//				lock.unlock();
//			}
//		}
//		return getAlbumInfoDB(albumId);
	}

	@Nullable
	private AlbumInfo getAlbumInfoDB(Long albumId){
		//因为需要给专辑标签赋值；albumAttributeValueVoList
		//查询专辑信息表
		AlbumInfo albumInfo = albumInfoMapper.selectById(albumId);
		//为了防止空指针
		if (null!=albumInfo){
			//根据专辑Id获取到标签数据：
			//select * from album_attribute_value where album_id = 1630;
			//wrapper
			LambdaQueryWrapper<AlbumAttributeValue> wrapper = new LambdaQueryWrapper<>();
			wrapper.eq(AlbumAttributeValue::getAlbumId,albumId);
			List<AlbumAttributeValue> albumAttributeValues = albumAttributeValueMapper.selectList(wrapper);
			albumInfo.setAlbumAttributeValueVoList(albumAttributeValues);
		}
		//返回数据
		return albumInfo;
	}

	@Override
	public void updateAlbumInfo(Long albumId, AlbumInfo albumInfo) {
		//先删除缓存的key：album:info:[1599]
//		String key = "album:["+albumId+"]";
//		redisTemplate.delete(key);

		albumInfo.setId(albumId);
		//更新主表
		albumInfoMapper.updateById(albumInfo);
		//更新从表
		//1-先删除在添加
		List<AlbumAttributeValue> albumAttributeValueVoList = albumInfo.getAlbumAttributeValueVoList();
		albumAttributeValueMapper.delete(new LambdaQueryWrapper<AlbumAttributeValue>().eq(AlbumAttributeValue::getAlbumId,albumId));
		albumAttributeValueVoList.forEach((albumAttributeValue)->{albumAttributeValue.setAlbumId(albumId);});
		//批量添加
		boolean b1 = albumAttributeValueService.saveBatch(albumInfo.getAlbumAttributeValueVoList());
		System.out.println("b1 = = = "+b1);

		//之前业务代码
        try {
            Thread.sleep(100);
        } catch (InterruptedException e) {
            throw new RuntimeException(e);
        }
		//删除
//		this.redisTemplate.delete();
//		redisTemplate.delete(key);
        //判断是否公开
		//判断IsOpen状态,0 不公开，1 公开
		if ("1".equals(albumInfo.getIsOpen())) {
		//调用上架方法；searchFeignClient.upperAlbum(albumId);
			rabbitService.sendMessage(MqConst.EXCHANGE_ALBUM,MqConst.ROUTING_ALBUM_UPPER,albumInfo.getId());
			//将专辑Id添加到布隆过滤器
			RBloomFilter<Object> bloomFilter = redissonClient.getBloomFilter(RedisConstant.ALBUM_BLOOM_FILTER);
			bloomFilter.add(albumInfo.getId());
		}else {
			//调用下架方法;	searchFeignClient.lowerAlbum(albumId);
			rabbitService.sendMessage(MqConst.EXCHANGE_ALBUM,MqConst.ROUTING_ALBUM_LOWER,albumInfo.getId());
		}

	}

	@Override
	public void removeAlbumInfo(Long albumId) {
		albumInfoMapper.deleteById(albumId);
		albumAttributeValueMapper.delete(new LambdaQueryWrapper<AlbumAttributeValue>().eq(AlbumAttributeValue::getAlbumId,albumId));
//		searchFeignClient.lowerAlbum(albumId);
		rabbitService.sendMessage(MqConst.EXCHANGE_ALBUM,MqConst.ROUTING_ALBUM_LOWER,albumId);
	}

	@Override
	public List<AlbumInfo> findUserAllAlbumList(Long userId) {
		LambdaQueryWrapper<AlbumInfo> wrapper = new LambdaQueryWrapper<>();
		wrapper.eq(AlbumInfo::getUserId, userId);
		wrapper.orderByDesc(AlbumInfo::getId);
		Page<AlbumInfo> albumInfoPage = new Page<>(1,100);
		Page<AlbumInfo> infoPage = albumInfoMapper.selectPage(albumInfoPage, wrapper);
		return infoPage.getRecords();
	}

	@Override
	public AlbumStatVo getAlbumStatVo(Long albumId) {
		return albumInfoMapper.getAlbumStatVo(albumId);
	}

    @Override
    public void updateStat(Long albumId, String statType, Integer count) {
        albumInfoMapper.updateStat(albumId,statType,count);
    }


}
